#include "Giraffe.h"
#include "EcoSystem.h"
#include <iostream>

Giraffe::Giraffe(EcoSystem *eco_system) :
Consumer(eco_system)
{
    set_alive();
    set_speed(0.4);
    //!!!!!!!!!!!!!!!!!!!!
    set_max_hp(1800);
    set_hp(get_max_hp());
    //!!!!!!!!!!!!!!!!!!!!
    set_init_speed(get_speed());
    ///
    set_life_span(LIFE_SPAN[get_species_id()] * (1 + max(min(0.2, EcoSystem::random_double() - 0.5), -0.2)));


}

Giraffe::~Giraffe() {}



Gdiplus::Image *Giraffe::get_entity_image() const
{
    static Gdiplus::Image *img = Gdiplus::Image::FromFile(L".\\images\\giraffe.png");
    return img;
}

const unsigned int Giraffe::get_species_id() const
{
    return GIRAFFE_SPECIES_ID;
}

Entity *Giraffe::new_entity() const
{
    return new Giraffe(eco_system);
}


bool Giraffe::prey(double speed)
{
    set_speed(speed);
    Entity *food = eco_system->find_prey(this);
    if (food != NULL)
    {
        if (food->get_hp() / food->get_max_hp() <= 0.4 && get_hp()>get_max_hp()*0.6) return false;
        //Wooooooooooow!!!I see my delicious dinner near me!!!
        if (!eco_system->try_eat(this, food))
        {
            /*
            *Suppose the position of the prey is target_position.
            *The direction that this animal should run toward is the direction of [(target_position) -(position of this animal)]
            *Normalize the vector [(target_position) -(position of this animal)] then times the speed we get displacement
            *{(position of this animal) + displacement} is the next position of this animal
            */
            Vector2D target_position = food->get_position();
            Vector2D distance = target_position - this->get_position();
            Vector2D displacement = distance * (1.0 / distance.modulus()) * get_speed();
            target_position = get_position() + displacement;
            this->set_position(target_position);
        }
        return true;
    }
    return false;//404 Prey not found.
}


void Giraffe::on_tick()
{
    set_age(get_age() + 1);
    set_hp(get_hp() - get_speed()*get_speed()/2);
    natural_growth();
    multiply();

    double factor = get_environment_factor();
    if (!avoid_predator(get_init_speed()*1.8*factor))
    {
        if (hungry() > 0.85){
            brownian_motion(get_init_speed()*factor);
        }
        else if (!prey(get_init_speed()*1.5*factor))
        {
            random_motion(get_init_speed()*1.25*factor);
        }
    }
}

int    Giraffe::get_cost_of_being_preyed() const
{
    return 0.05*get_hp();
}
int    Giraffe::get_gain_after_being_preyed() const
{
    return 0.25*get_hp();
}